import { Cell, Graph, Model, Node } from "@antv/x6";
import { Clipboard } from '@antv/x6-plugin-clipboard';
import { Export } from "@antv/x6-plugin-export";
import { History } from '@antv/x6-plugin-history';
import { Keyboard } from '@antv/x6-plugin-keyboard';
import { Selection } from '@antv/x6-plugin-selection';
import { Snapline } from '@antv/x6-plugin-snapline';
import { Transform } from '@antv/x6-plugin-transform';
import { GraphConfigService, PluginSetting } from "./graph-config.service";

export abstract class GraphBase {
  protected container?: HTMLDivElement;
  protected graph!: Graph;
  constructor(protected service: GraphConfigService) {
  }
  Init(container: HTMLDivElement) {
    this.container = container;
    this.initGraph();
    this.registers();
    this.setPlugins();
    this.bindKeys();
  }

  destroy() {
    console.log("destory");
  }
  
  /**
   * initialize graph
   */
  protected abstract initGraph(): void;
  /**
   *  register  elements to the graph
   */
  protected abstract registers(): void;
  protected setPlugins() {
    const { graph } = this;
    const setting = this.getPluginSetting();
    // 设置插件
    if (setting.transform) {
      graph
        .use(
          new Transform({
            resizing: true,
            rotating: true,
          }));
    }
    if (setting.selecton) {
      graph.use(
        new Selection({
          movable: false,
          rubberband: true,
          showNodeSelectionBox: true,
        }));
    }
    if (setting.snapline) {
      graph.use(new Snapline());
    }
    if (setting.keyboard) {
      graph.use(new Keyboard());
    }
    if (setting.clipboard) {
      graph.use(new Clipboard());
    }
    if (setting.history) {
      graph.use(new History());
    }
    // if(setting.minimap){
    //   graph.use(new MiniMap())
    // }
    if (setting.export) {
      graph.use(new Export());
    }
  }
  protected abstract getPluginSetting(): Partial<PluginSetting>;
  protected bindKeys(): void {

  }

  createNode(data: Node.Metadata) {
    return this.graph.createNode(data);
  }

  fromJSON(data: Model.FromJSONData): void {
    this.graph.fromJSON(data);
  }

  toJSON(): { cells: Cell.Properties[]; } {
    return this.graph.toJSON();
  }
  getNodes(): Node<Node.Properties>[] {
    return this.graph.getNodes();
  }
  loadNodes(nodes: Node<Node.Properties>[]) {
    this.graph.clearCells();
    this.graph.addNodes(nodes);
  }


}
